/*****************************************************************************
 *
 *                      HUSONG PROPRIETARY INFORMATION
 *
 *          The information contained herein is proprietary to HUSONG
 *           and shall not be reproduced or disclosed in whole or in part
 *                    or used for any design or manufacture
 *              without direct written authorization from HUSONG.
 *
 *            Copyright (c) 2015 by HUSONG.  All rights reserved.
 *
 *****************************************************************************/
package me.send.framework.util;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.ConnectionFactoryBuilder.Protocol;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import net.spy.memcached.internal.OperationFuture;
import net.spy.memcached.ops.OperationStatus;

/**
 * @author maxmin
 *
 * @date 2015年8月3日 下午2:24:11
 */
public class CacheUtil {

	// 控制台上的“内网地址”
	private static int IS_LOCAL = 1;
	private static int IS_REMOTE = 2;
	private int isLocalOrRemot = IS_LOCAL;
	private String host;
	private String port; 
	private String username;
	private String password;
	private static final CacheUtil cacheUtil = new CacheUtil() ;
	private static MemcachedClient client;
	
	public static CacheUtil getInstance(){
		return cacheUtil;
	}
	
	private MemcachedClient getClient(){
		if (client == null ) {
			try {
				System.out.println("host:"+getHost()+",port:"+getPort());
					if (isLocalOrRemot == IS_LOCAL) {
						// 本地缓存
						client = new MemcachedClient(new BinaryConnectionFactory(),AddrUtil.getAddresses(host + ":" + port));
					}else if (isLocalOrRemot == IS_REMOTE) {
						// 远程服务器缓存
						AuthDescriptor authDescriptor = new AuthDescriptor(new String[] { "PLAIN" }, new PlainCallbackHandler(username,password));
						client = new MemcachedClient(new ConnectionFactoryBuilder().setProtocol(Protocol.BINARY).setAuthDescriptor(authDescriptor).build(), AddrUtil.getAddresses(host + ":" + port));
					}
				LoggerUtils.warn(getClass().getName(), "cache util init end!");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return client;
	}
	
	public  boolean delete(String key) {
		try {
			OperationFuture<Boolean> future = getClient().delete(key);
			return future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return false;
	}

	public  boolean add(String key, int exp, Object value) {
		try {
			OperationFuture<Boolean> future = getClient().add(key, exp, value);
			return future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return false;
	}

	public  boolean set(String key, int exp, Object value) {
		try {
			OperationFuture<Boolean> future = getClient().set(key, exp, value);
			return future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return false;
	}

	public  boolean replace(String key, int exp, Object value) {
		try {
			OperationFuture<Boolean> future = getClient().replace(key, exp, value);
			OperationStatus status = future.getStatus();
			System.out.println(status.getMessage());
			return future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return false;
	}

	public  Object get(String key) {
		return getClient().get(key);
	}

	/**
	 * @return the isLocalOrRemot
	 */
	public int getIsLocalOrRemot() {
		return isLocalOrRemot;
	}

	/**
	 * @param isLocalOrRemot the isLocalOrRemot to set
	 */
	public void setIsLocalOrRemot(int isLocalOrRemot) {
		this.isLocalOrRemot = isLocalOrRemot;
	}

	/**
	 * @return the host
	 */
	public String getHost() {
		return host;
	}

	/**
	 * @param host the host to set
	 */
	public void setHost(String host) {
		this.host = host;
	}

	/**
	 * @return the port
	 */
	public String getPort() {
		return port;
	}

	/**
	 * @param port the port to set
	 */
	public void setPort(String port) {
		this.port = port;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}
}
